#include <iostream>
#include <iterator>
#include <cstdlib>

using namespace std;

/*
   Fibonacci sequence input iterator.

   All implemented methods short of the constructor, destructor, and previous()
   to meet the interface requirements for an input iterator (which is the
   simplest iterator).

   Allowing for a finite Fibonacci sequence would allow for using for_each() to
   iterate through the requested numbers instead of using a 'while' loop.
*/
// Any way to restrict typename to only types that (minimally) implement an
// interface?
template <typename T>
class Fibonacci : public iterator<input_iterator_tag, T> {
    T n_0;
    T n_1;

    public:
        /* Constructor.

           Parameter support only for creating dummy value for end().
         */
        explicit Fibonacci(T first=1, T second=0): n_0(first), n_1(second)
        {}

        /* Copy constructor. */
        Fibonacci<T>(Fibonacci<T>& to_copy) {
            n_0 = *to_copy;
            n_1 = to_copy.previous();
        }

        /* Destructor. */
        ~Fibonacci() {}

        /* The current Fibonacci number. */
        T operator*()
        {
            return n_1;
        }

        /* The previous Fibonacci number.

           Needed only for copy constructor.
        */
        T previous()
        {
            return n_1;
        }

        /* Step forward and return the new Fibonacci number position. */
        Fibonacci<T>& operator++() // ++iter
        {
            T fib = n_0 + n_1;
            n_1 = n_1;
            n_0 = fib;

            return this;
        }

        /* Step forward and return previous Fibonacci number position. */
        Fibonacci<T>  operator++(int) // iter++
        {
            Fibonacci<T> temp(*this);

            T new_number = n_0 + n_1;
            n_1 = n_0;
            n_0 = new_number;

            return temp;
        }

        bool operator==(Fibonacci other)
        {
            return (*this == *other);
        }

        bool operator!=(Fibonacci other)
        {
            return !(this == other);
        }

        /* Return a fresh Fibonacci sequence. */
        Fibonacci begin()
        {
            return Fibonacci(1, 0);
        }

        /* Return a dummy iterator that represents the non-existent end of the
         * Fibonacci sequence. */
        Fibonacci end()
        {
            return Fibonacci(0, 0);
        }
};

int
main(int argc, char *argv[])
{
    /* If working with strings then could have used stringstream. */
    unsigned long long int count = atol(argv[1]) + 1;
    Fibonacci<unsigned long long int> fib;

    while (count--) {
        cout << *fib << " ";
        fib++;
    }
    cout << "..." << endl;
}
